#include "bsp.h"

#define CONFIG_UART_PORT_NUM  UART_NUM_0
#define CONFIG_UART_BAUD_RATE 115200
#define CONFIG_UART_TX_IO     UART_PIN_NO_CHANGE
#define CONFIG_UART_RX_IO     UART_PIN_NO_CHANGE

#define CONFIG_RETRY_NUM      5

static const char *TAG = "app_main";

extern SSD1306_t dev;
extern char ShowChar[20];

static void uart_initialize()
{
    uart_config_t uart_config = {
        .baud_rate = CONFIG_UART_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    ESP_ERROR_CHECK(uart_param_config(CONFIG_UART_PORT_NUM, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(CONFIG_UART_PORT_NUM, CONFIG_UART_TX_IO, CONFIG_UART_RX_IO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
    ESP_ERROR_CHECK(uart_driver_install(CONFIG_UART_PORT_NUM, 8 * ESPNOW_DATA_LEN, 8 * ESPNOW_DATA_LEN, 0, NULL, 0));
}

static void wifi_init()
{
    ESP_ERROR_CHECK(esp_netif_init());
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
    ESP_ERROR_CHECK(esp_wifi_start());
}

static void uart_read_task(void *arg)
{
    esp_err_t ret  = ESP_OK;
    uint32_t count = 0;
    size_t size    = 0;
    uint8_t *data  = ESP_CALLOC(1, ESPNOW_DATA_LEN);

    ESP_LOGI(TAG, "Uart read handle task is running");

    espnow_frame_head_t frame_head = {
        .retransmit_count = CONFIG_RETRY_NUM,
        .broadcast        = true,
    };

    for (;;) {
        size = uart_read_bytes(CONFIG_UART_PORT_NUM, data, ESPNOW_DATA_LEN, pdMS_TO_TICKS(10));
        ESP_ERROR_CONTINUE(size <= 0, "");

        ret = espnow_send(ESPNOW_TYPE_DATA, ESPNOW_ADDR_BROADCAST, data, size, &frame_head, portMAX_DELAY);
        ESP_ERROR_CONTINUE(ret != ESP_OK, "<%s> espnow_send", esp_err_to_name(ret));

        ESP_LOGI(TAG, "espnow_send, count: %d, size: %d, data: %s", count++, size, data);
        memset(data, 0, ESPNOW_DATA_LEN);
    }

    ESP_LOGI(TAG, "Uart handle task is exit");

    ESP_FREE(data);
    vTaskDelete(NULL);
}

/*
static void uart_write_task(void *arg)
{
    esp_err_t ret  = ESP_OK;
    uint32_t count = 0;
    char *data     = ESP_MALLOC(ESPNOW_DATA_LEN);
    size_t size   = ESPNOW_DATA_LEN;
    uint8_t addr[ESPNOW_ADDR_LEN] = {0};
    wifi_pkt_rx_ctrl_t rx_ctrl    = {0};

    ESP_LOGI(TAG, "Uart write task is running");

    for (;;) {
        ret = espnow_recv(ESPNOW_TYPE_DATA, addr, data, &size, &rx_ctrl, portMAX_DELAY);
        ESP_ERROR_CONTINUE(ret != ESP_OK, "<%s>", esp_err_to_name(ret));

        ESP_LOGI(TAG, "espnow_recv, <%d> [" MACSTR "][%d][%d][%d]: %.*s", 
                count++, MAC2STR(addr), rx_ctrl.channel, rx_ctrl.rssi, size, size, data);


        for(count=0;count<size;count++)
        {
            printf("data[%d]==%d\r\n",count,data[count]);
        }
        

        // uart_write_bytes(CONFIG_UART_PORT_NUM, data, size);
    }

    ESP_LOGW(TAG, "Uart send task is exit");

    ESP_FREE(data);
    vTaskDelete(NULL);
}
*/



static void Node_Recv_task(void *arg)
{
    esp_err_t ret  = ESP_OK;
    //uint32_t count = 0;
    char *data     = ESP_MALLOC(ESPNOW_DATA_LEN);
    size_t size   = ESPNOW_DATA_LEN;
    uint8_t addr[ESPNOW_ADDR_LEN] = {0};
    wifi_pkt_rx_ctrl_t rx_ctrl    = {0};

    ESP_LOGI(TAG, "Node_Recv_task task is running");

    while(1)
    {
        ret = espnow_recv(ESPNOW_TYPE_DATA, addr, data, &size, &rx_ctrl, portMAX_DELAY);
        ESP_ERROR_CONTINUE(ret != ESP_OK, "<%s>", esp_err_to_name(ret));
        Tospo_espnow_process_data(addr, data,&size, &rx_ctrl);//接收数据统一放入协议处理里进行处理。这里只负责传输下！

    }
    ESP_FREE(data);
    vTaskDelete(NULL);
}


static void Node_Connect_task(void *arg)
{
    esp_err_t ret  = ESP_OK;
    ESP_LOGI(TAG, "Node_Connect_task task is running");

    uint32_t count = 0;
    size_t size    = 0;
    uint8_t *data  = ESP_CALLOC(1, ESPNOW_DATA_LEN);


    espnow_frame_head_t frame_head = {
        .retransmit_count = CONFIG_RETRY_NUM,
        .broadcast        = true,
    };

    data[0] = HEAD_ONE;
    data[1] = HEAD_TWO;
    data[2] = COLTD_ONE;
    data[3] = COLTD_TWO;
    data[4] = PROTOCOL_TYPE_TWO;
    data[5] = 0;
    data[6] = 0;
    data[7] = 0;
    data[8] = PROTOCOL_TYPE_TWO_CMD_SEV;
    data[9] = RET_FLAG_NO;
    data[10] = 1;
    data[11] = 0;
    data[12] = (uint8_t)App.Tospo_Edu_Rssi;

    size = 13;

    while(1)
    {
     
        vTaskDelay((3000)/portTICK_RATE_MS);//3s发送一次

        data[11] = count%2;
        data[12] = (uint8_t)App.Tospo_Edu_Rssi;
        
        ret = espnow_send(ESPNOW_TYPE_DATA, ESPNOW_ADDR_BROADCAST, data, size, &frame_head, portMAX_DELAY);
        ESP_ERROR_CONTINUE(ret != ESP_OK, "<%s> espnow_send", esp_err_to_name(ret));
        count++;
        LED1_ON;
    }   
    ESP_FREE(data);
    vTaskDelete(NULL);
}

/*
static void Node_Connect_task(void *arg)
{
    esp_err_t ret  = ESP_OK;
    ESP_LOGI(TAG, "Node_Connect_task task is running");

    //uint32_t count = 0;
    size_t size    = 0;
    uint8_t *data  = ESP_CALLOC(1, ESPNOW_DATA_LEN);


    espnow_frame_head_t frame_head = {
        .retransmit_count = CONFIG_RETRY_NUM,
        .broadcast        = true,
    };

    data[0] = HEAD_ONE;
    data[1] = HEAD_TWO;
    data[2] = COLTD_ONE;
    data[3] = COLTD_TWO;
    data[4] = PROTOCOL_TYPE_TWO;
    data[5] = 0;
    data[6] = 0;
    data[7] = 0;
    data[8] = PROTOCOL_TYPE_TWO_CMD_SIX;
    data[9] = RET_FLAG_NO;
    data[10] = 0;

    size = 11;

    while(1)
    {
     
        ///vTaskDelay(((esp_random()%10+1)*1000)/portTICK_RATE_MS);//随机1~10s内发送组网信号

        vTaskDelay((2000)/portTICK_RATE_MS);//3s发送一次
        
        App.Tosop_Is_CONNECT_FLAG=0;
        if(App.Tosop_Is_CONNECT_FLAG == 0)
        {
            ret = espnow_send(ESPNOW_TYPE_DATA, ESPNOW_ADDR_BROADCAST, data, size, &frame_head, portMAX_DELAY);
            ESP_ERROR_CONTINUE(ret != ESP_OK, "<%s> espnow_send", esp_err_to_name(ret));

            App.Tospo_Send_count++;
            LED1_ON;

            sprintf(&ShowChar[0], "S:%06dR:%06d", App.Tospo_Send_count,App.Tospo_Recv_count);
            ssd1306_display_text(&dev, 3, ShowChar, strlen(ShowChar), false);

            ESP_LOGI(TAG, "I want to connect!!!");
        }
        else
        {

        }
    }   
    ESP_FREE(data);
    vTaskDelete(NULL);
}
*/

void app_main()
{
   

    esp_log_level_set("*", ESP_LOG_INFO);

    esp_storage_init();
    esp_event_loop_create_default();

    Tospo_bsp_init();

    wifi_init();

    espnow_config_t espnow_config = ESPNOW_INIT_CONFIG_DEFAULT();
    espnow_config.qsize.data      = 64;
    espnow_init(&espnow_config);

    /* uart initialization */ 

    ///xTaskCreate(uart_read_task, "uart_read_task", 4 * 1024, NULL, tskIDLE_PRIORITY + 1, NULL);
    //xTaskCreate(uart_write_task, "uart_write_task", 4 * 1024, NULL, tskIDLE_PRIORITY + 1, NULL);

    xTaskCreate(Node_Recv_task, "Node_Recv_task", 4 * 1024, NULL, tskIDLE_PRIORITY + 1, NULL);//节点接收处理函数

    xTaskCreate(Node_Connect_task, "Node_Connect_task", 4 * 1024, NULL, tskIDLE_PRIORITY + 1, NULL);//节点信息实时接收与反馈

    xTaskCreate(vTask_Menu, "vTask_Menu", 4* 1024, NULL, tskIDLE_PRIORITY + 1, NULL);//显示界面主函数

}
